package com.tree.backend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tree.backend.entity.dto.user.UserAddDTO;
import com.tree.backend.entity.dto.user.UserQueryDTO;
import com.tree.backend.entity.dto.user.UserUpdateDTO;
import com.tree.backend.entity.pojo.Department;
import com.tree.backend.entity.pojo.User;
import com.tree.backend.entity.vo.PageVO;
import com.tree.backend.entity.vo.auth.LoginResponseVO;
import com.tree.backend.entity.vo.auth.UserInfoVO;
import com.tree.backend.entity.vo.user.RoleTypeVO;
import com.tree.backend.entity.vo.user.UserVO;
import com.tree.backend.mapper.DepartmentMapper;
import com.tree.backend.mapper.UserMapper;
import com.tree.backend.service.IUserService;
import com.tree.backend.utils.JwtUtil;
import com.tree.backend.utils.UserContext;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 系统用户表 服务实现类
 * </p>
 */
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    private final JwtUtil jwtUtil;
    private final DepartmentMapper departmentMapper;

    @Override
    public LoginResponseVO login(String username, String password) {
        // 查询用户是否存在
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        User user = this.baseMapper.selectOne(queryWrapper);

        // 判断用户是否存在
        if (Objects.isNull(user)) {
            throw new RuntimeException("用户名或密码错误");
        }

        // 判断用户状态是否启用
        if (user.getStatus() == 0) {
            throw new RuntimeException("账号已被禁用，请联系管理员");
        }

        // 验证密码（这里假设密码是明文存储，实际应该使用加密方式）
        if (!Objects.equals(password, user.getPassword())) {
            throw new RuntimeException("用户名或密码错误");
        }

        // 更新最后登录时间
        user.setLastLoginTime(LocalDateTime.now());
        this.baseMapper.updateById(user);

        // 生成token
        String token = jwtUtil.generateToken(username);

        // 构建登录响应
        LoginResponseVO responseVO = new LoginResponseVO();
        responseVO.setToken(token);
        responseVO.setUsername(username);
        responseVO.setRoleType(user.getRoleType());

        return responseVO;
    }

    @Override
    public void logout(String username) {
        // 在实际项目中，可能需要将token加入黑名单或缓存中标记为已失效
        // 这里简化处理，只记录日志或进行其他业务操作
        System.out.println("用户" + username + "已登出");
    }

    @Override
    public UserInfoVO getUserInfo(String username) {
        // 查询用户信息
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        User user = this.baseMapper.selectOne(queryWrapper);

        if (Objects.isNull(user)) {
            throw new RuntimeException("用户不存在");
        }

        // 构建用户信息响应
        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtils.copyProperties(user, userInfoVO);

        return userInfoVO;
    }

    @Override
    public PageVO<UserVO> getUsers(UserQueryDTO queryDTO) {
        // 构建分页查询条件
        Page<User> page = new Page<>(queryDTO.getPage(), queryDTO.getPageSize());
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        
        // 添加查询条件
        if (Objects.nonNull(queryDTO.getUsername())) {
            queryWrapper.like("username", queryDTO.getUsername());
        }
        if (Objects.nonNull(queryDTO.getRealName())) {
            queryWrapper.like("real_name", queryDTO.getRealName());
        }
        if (Objects.nonNull(queryDTO.getDepartmentId())) {
            queryWrapper.eq("department_id", queryDTO.getDepartmentId());
        }
        if (Objects.nonNull(queryDTO.getRoleType())) {
            queryWrapper.eq("role_type", queryDTO.getRoleType());
        }
        if (Objects.nonNull(queryDTO.getStatus())) {
            queryWrapper.eq("status", queryDTO.getStatus());
        }
        // 执行查询
        Page<User> userPage = this.baseMapper.selectPage(page, queryWrapper);
        
        // 转换为VO对象
        List<UserVO> userVOList = new ArrayList<>();
        for (User user : userPage.getRecords()) {
            UserVO userVO = new UserVO();
            BeanUtils.copyProperties(user, userVO);
            // 设置部门名称和角色名称（实际应该从数据库查询）
            userVO.setDepartmentName(getDepartmentName(user.getDepartmentId()));
            userVO.setRoleName(getRoleName(user.getRoleType()));
            userVOList.add(userVO);
        }
        
        // 构建分页响应
        PageVO<UserVO> pageVO = new PageVO<>();
        pageVO.setRecords(userVOList);
        pageVO.setTotal(userPage.getTotal());
        pageVO.setCurrent(userPage.getCurrent());
        pageVO.setSize(userPage.getSize());
        
        return pageVO;
    }

    @Override
    public UserVO getUserById(Integer id) {
        User user = this.baseMapper.selectById(id);
        if (Objects.isNull(user)) {
            throw new RuntimeException("用户不存在");
        }
        
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        userVO.setDepartmentName(getDepartmentName(user.getDepartmentId()));
        userVO.setRoleName(getRoleName(user.getRoleType()));
        
        return userVO;
    }

    @Override
    public void addUser(UserAddDTO userAddDTO) {
        // 检查用户名是否已存在
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", userAddDTO.getUsername());
        if (this.baseMapper.selectOne(queryWrapper) != null) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 创建用户对象
        User user = new User();
        BeanUtils.copyProperties(userAddDTO, user);
        
        // 设置默认密码（实际应该加密）
        user.setPassword("123456");
        
        // 设置创建时间和更新时间
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        
        // 保存用户
        this.baseMapper.insert(user);
    }

    @Override
    public void updateUser(Integer id, UserUpdateDTO userUpdateDTO) {
        // 检查用户是否存在
        User user = this.baseMapper.selectById(id);
        if (Objects.isNull(user)) {
            throw new RuntimeException("用户不存在");
        }
        
        // 检查用户名是否重复（排除当前用户）
        if (Objects.nonNull(userUpdateDTO.getUsername())) {
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("username", userUpdateDTO.getUsername());
            queryWrapper.ne("id", id);
            if (this.baseMapper.selectOne(queryWrapper) != null) {
                throw new RuntimeException("用户名已存在");
            }
        }
        
        // 更新用户信息
        BeanUtils.copyProperties(userUpdateDTO, user);
        user.setUpdateTime(LocalDateTime.now());
        
        // 保存更新
        this.baseMapper.updateById(user);
    }

    @Override
    public void deleteUser(Integer id) {
        // 检查用户是否存在
        User user = this.baseMapper.selectById(id);
        if (Objects.isNull(user)) {
            throw new RuntimeException("用户不存在");
        }
        
        // 执行删除
        this.baseMapper.deleteById(id);
    }

    @Override
    public void updateUserStatus(Integer id, Integer status) {
        // 检查用户是否存在
        User user = this.baseMapper.selectById(id);
        if (Objects.isNull(user)) {
            throw new RuntimeException("用户不存在");
        }
        
        // 更新状态
        user.setStatus(status);
        user.setUpdateTime(LocalDateTime.now());
        
        // 保存更新
        this.baseMapper.updateById(user);
    }

    @Override
    public List<RoleTypeVO> getRoleTypes() {
        List<RoleTypeVO> roleTypes = new ArrayList<>();
        // 使用Map存储角色类型，便于管理和维护
        Map<Integer, String> roleMap = new HashMap<>();
        roleMap.put(1, "普通员工");
        roleMap.put(2, "部门经理");
        roleMap.put(3, "财务人员");
        roleMap.put(4, "系统管理员");
        
        // 遍历Map创建角色类型对象
        for (Map.Entry<Integer, String> entry : roleMap.entrySet()) {
            roleTypes.add(createRoleType(entry.getKey(), entry.getValue()));
        }
        
        return roleTypes;
    }

    @Override
    public List<UserVO> getAllUsers() {
        // 查询所有启用状态的用户
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 1) // 只查询启用状态的用户
                   .orderByAsc("create_time"); // 按创建时间排序
        
        List<User> users = this.baseMapper.selectList(queryWrapper);
        
        // 转换为VO列表
        List<UserVO> userVOs = new ArrayList<>();
        for (User user : users) {
            UserVO userVO = new UserVO();
            BeanUtils.copyProperties(user, userVO);
            // 设置部门名称
            userVO.setDepartmentName(getDepartmentName(user.getDepartmentId()));
            // 设置角色名称
            userVO.setRoleName(getRoleName(user.getRoleType()));
            userVOs.add(userVO);
        }
        
        return userVOs;
    }

    @Override
    public String getUserByUserName() {
        // 从JWT中获取用户名
        // 当前线程池获取
        return UserContext.getUsername();
    }

    @Override
    public PageVO<UserVO> searchUsers(UserQueryDTO queryDTO) {
        // 搜索功能可以复用getUsers方法，因为查询条件是一样的
        return getUsers(queryDTO);
    }
    
    // 辅助方法：根据部门ID获取部门名称
    private String getDepartmentName(Integer departmentId) {
        if (departmentId == null) {
            return "未知部门";
        }
        // 从数据库查询部门信息
        Department department = departmentMapper.selectById(departmentId);
        return department != null ? department.getDeptName() : "未知部门";
    }
    
    // 辅助方法：根据角色类型获取角色名称
    private String getRoleName(Integer roleType) {
        // 使用Map存储角色类型映射，避免硬编码
        Map<Integer, String> roleMap = new HashMap<>();
        roleMap.put(1, "普通员工");
        roleMap.put(2, "部门经理");
        roleMap.put(3, "财务人员");
        roleMap.put(4, "系统管理员");
        return roleMap.getOrDefault(roleType, "未知角色");
    }
    
    // 辅助方法：创建角色类型对象
    private RoleTypeVO createRoleType(Integer value, String label) {
        RoleTypeVO roleType = new RoleTypeVO();
        roleType.setValue(value);
        roleType.setLabel(label);
        return roleType;
    }
}
